package com.koron.auth.util;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

/**
 * @ClassName RSATool
 * @description
 * @Author zhouj
 * @Date 2021/12/30 18:27
 */
public class RSATool {
    static Logger logger = LoggerFactory.getLogger(RSATool.class);

    /**
     * 由数字获得证书
     *
     * @param modules  模
     * @param keyStr   指数
     * @param isPublic 是否公钥，否为私钥
     * @return 返回获取的证书
     * @throws NoSuchAlgorithmException 算法错误异常
     * @throws InvalidKeySpecException  证书异常
     */
    public static Key getKey(BigInteger modules, BigInteger keyStr, boolean isPublic) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        if (isPublic)
            return keyFactory.generatePublic(new RSAPublicKeySpec(modules, keyStr));
        else
            return keyFactory.generatePrivate(new RSAPrivateKeySpec(modules, keyStr));
    }

    /**
     * 进行签名
     *
     * @param content 内容,117字节最长
     * @param key     签名用的KEY
     * @param mode    方式，加密或解密 {@link Cipher#ENCRYPT_MODE} {@link Cipher#DECRYPT_MODE}
     * @return 加密(或解密)后的字节串
     * @throws InvalidKeyException       证书异常
     * @throws NoSuchAlgorithmException  算法异常
     * @throws NoSuchPaddingException    间隔异常
     * @throws IllegalBlockSizeException 数据块异常
     * @throws BadPaddingException       分隔异常
     */
    public static byte[] sign(byte[] content, Key key, int mode) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
            IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(mode, key);
        return cipher.doFinal(content);
    }
}
